package com.lsy.poi.row;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.PropertyUtils;

import com.lsy.poi.Student;

//import org.apache.commons.beanutils.BeanUtils;
//import org.apache.commons.beanutils.PropertyUtils;

public class RowMapper<T> {

	//1、javaBean RowMapping
//	private List<?> hookList; // TODO: 如果是 List<String> 貌似 没法做了。。。
	private String[] propertyNames;
	private Class<T> clazz; // TODO: 如果是 List<String> 貌似 没法做了。。。

	//2、基础类型 RowMapping
	private int columnIndex; //将哪一个 列 上的 值 落地到 基础类型 变量 上

	public RowMapper(String[] propertyNames, Class<T> clazz) {
		this.propertyNames = propertyNames;
		this.clazz = clazz;
	}
	
	public RowMapper(int columnIndex) {
		this.columnIndex = columnIndex;
	}


//	public <T> RowParser(List<T> hookList, RowMapper<T> rowMapper) {
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		RowMapper<Student> asd = new RowMapper<>(new String[]{"aaa", "bbb", "ccc"},  Student.class);
		
		List<Student> zxc = new ArrayList<Student>();
		
		asd.mapRow(zxc, new String[]{"aaa", "bbb", "ccc"});
		
	}

	/**
	 * List<?> => List<T> 之间的 接力方法
	 */
	public final void mapRow0(List<?> hookList0, Object[] cellValues) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		@SuppressWarnings("unchecked")
		List<T> hookList = (List<T>) hookList0;
		
		mapRow(hookList, cellValues);
	}

	
	public void mapRow(List<T> hookList, Object[] cellValues) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		//TODO: 如果 cellValues.length < propertyNames.length，这会报错的 
		
		T ele = setProperties(cellValues);
		
		hookList.add(ele);
	}
	
	@SuppressWarnings("unchecked")
	protected T setProperties(Object[] cellValues) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		T ele;
		if (propertyNames != null && clazz != null) {
			ele = clazz.newInstance();

			for (int i = 0; i < propertyNames.length; i++) {
				String propertyName = propertyNames[i];
				
				/**
				 * 由于使用了 函数indexer，所以 row 包含的列数 是 不固定的，可能会 小于 "属性映射" 所需的  propertyNames 的 length
				 * 这时 直接 break 吧
				 * 
				 * 当然，你也可以 自定义 rowMapper，自己决定 如何处理这个问题
				 */
				if(i >= cellValues.length) break;
				
				Object cellValue = cellValues[i];

				/**
				 * propertyName==null 是用来 空开位置 用的 cellValue!=null
				 */
				if ((propertyName != null)) {

					// 属性值装载
					//TODO: BeanUtils.setProperty() 当为 日期类型  设置 null，会发生报错
					// BeanUtils.setProperty(ele, propertyName, cellValue);
					PropertyUtils.setProperty(ele, propertyName, cellValue);
				}
			}
		} else {

			/**
			 * 基础类型：使用 List<String>、List<Integer> 来接受 row 的 数据，但此时 只会接受 第 1 列 的 数据 
			 * 如果没有 定义 propertyNames，则认为：只取 Object[] cellValues 的 第一个元素
			 */
			ele = (T) cellValues[columnIndex];
		}
		return ele;
	}



	public String[] getPropertyNames() {
		return propertyNames;
	}

	public void setPropertyNames(String[] propertyNames) {
		this.propertyNames = propertyNames;
	}

	public Class<T> getClazz() {
		return clazz;
	}
	
	public void setClazz(Class<T> clazz) {
		this.clazz = clazz;
	}


	public int getColumnIndex() {
		return columnIndex;
	}


	public void setColumnIndex(int columnIndex) {
		this.columnIndex = columnIndex;
	}

	
	

	
	// private

	// public void mapRow(List<Student> hookList, Student ele) {
	//
	// }
	// private Class<T> clazz;
	// private String[] properties = {"id", "name", "address", "birthDay"};
	//
	// public RowMapper(Class<T> clazz, String[] properties) {
	// super();
	// this.clazz = clazz;
	// this.properties = properties;
	// }
	//
	//
	// public T mapRow(Object[] cellValues) throws InstantiationException,
	// IllegalAccessException, InvocationTargetException {
	// T ele = clazz.newInstance();
	//
	// for(int i=0; i<properties.length; i++) {
	//
	// String property = properties[i];
	// Object cellValue = cellValues[i];
	//
	// BeanUtils.setProperty(ele, property, cellValue);
	// }
	//
	//
	// return ele;
	// // for (String columnLabel : headers) {
	// // //3.2、通过 列名，从 resultSet 中获取 列值
	// // Object columnValue = resultSet.getObject(columnLabel);
	// // //System.out.println(columnLabel + ": " + columnValue);
	// //
	// // //3.3、通过 反射，为 javaBean 对象设置属性值
	// // //ReflectionUtils.setFieldValue(ele, columnLabel, columnValue);
	// // BeanUtils.setProperty(ele, columnLabel, columnValue);
	// // }
	//
	// // eleList.add(ele);
	// //
	// // return null;
	// }
	//
	// @Test
	// public void foo() throws InstantiationException, IllegalAccessException,
	// InvocationTargetException {
	// Class<Student> clazz = Student.class;
	//
	// Student ele = clazz.newInstance();
	//
	// Object[] cellValues = {33, "张三", "上海", new Date()};
	//
	// String[] properties = {"id", "name", "address", "birthDay"};
	//
	//
	// // Map<String, Object> m1 = new HashMap<String, Object>();
	// // m1.put("aaa", 123);
	// // m1.put("bbb", 456);
	// // m1.put("ccc", 789);
	// // System.out.println(m1);
	//
	// for(int i=0; i<properties.length; i++) {
	//
	// String property = properties[i];
	// Object cellValue = cellValues[i];
	//
	// BeanUtils.setProperty(ele, property, cellValue);
	// }
	//
	// System.out.println(ele);
	// //
	// //
	// // for (String columnLabel : headers) {
	// // //3.2、通过 列名，从 resultSet 中获取 列值
	// // Object columnValue = resultSet.getObject(columnLabel);
	// // //System.out.println(columnLabel + ": " + columnValue);
	// //
	// // //3.3、通过 反射，为 javaBean 对象设置属性值
	// // //ReflectionUtils.setFieldValue(ele, columnLabel, columnValue);
	// // BeanUtils.setProperty(ele, columnLabel, columnValue);
	// // }
	// //
	// // eleList.add(ele);
	// }


	
	
//	
//	
//	for (String columnLabel : headers) {
//		//3.2、通过 列名，从  resultSet 中获取 列值
//		Object columnValue = resultSet.getObject(columnLabel);
//		//System.out.println(columnLabel + ": " + columnValue);
//		
//		//3.3、通过 反射，为 javaBean 对象设置属性值
//		//ReflectionUtils.setFieldValue(ele, columnLabel, columnValue);
//		BeanUtils.setProperty(ele, columnLabel, columnValue);
//	}
//	
//	eleList.add(ele);
	
/**
 * rowMapper 
 * 参数1:Object[] cellValues 的 下标
 * 参数2:实体类的 属性值，使用 BeanProperties 工具进行处理
 * 参数3:实体类（是一个 集合）  Class<T> clazz
 * 
 * 
 * 默认的 方式就是：通过 BeanProperties 把 属性值 设置到 实体类上
 * 也可以 补充这个 方法，补充方法的 第一行 可以 super.默认方法()
 * 
 * Object obj = PropertyUtils.getProperty(content, propertyName);
 * 
 * 
 * public static <T> List<T> query(Class<T> clazz, String sql, Object... args) {
 * 		。。。
 * 		while(resultSet.next()) {
			T ele = clazz.newInstance();
			
			for (String columnLabel : headers) {
				//3.2、通过 列名，从  resultSet 中获取 列值
				Object columnValue = resultSet.getObject(columnLabel);
				//System.out.println(columnLabel + ": " + columnValue);
				
				//3.3、通过 反射，为 javaBean 对象设置属性值
				//ReflectionUtils.setFieldValue(ele, columnLabel, columnValue);
				BeanUtils.setProperty(ele, columnLabel, columnValue);
			}
			
			eleList.add(ele);
		}
		
		。。。
	}
 * 
 */

}
